# -*- coding: utf-8 -*-

#   This file is part of emesene.
#
#    Eval plugin is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    Eval plugin is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with emesene; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

VERSION = '0.1'
import gtk
import time
import gobject
import gettext
import datetime

import Plugin

_ = gettext.gettext
default_msg = _('%days days %hours hours %minutes minutes for the date')
default_done_msg = _('The countdown is done!')

class ConfigWindow(gtk.Window):
    '''The configuration window for the plugin'''

    def __init__(self, callback, stamp=None, msg=None, done_msg=None):
        '''object constructor, the parameters are used to set the default
        values'''
        gtk.Window.__init__(self)

        self.stamp = stamp or time.time()
        self.msg = msg or default_msg 
        self.done_msg = done_msg or default_done_msg
        self.callback = callback
        self.dst = 0

        # Gtk part
        self.set_title(_('Countdown config'))
        self.set_default_size(430, 360)
        
        self.vbox = gtk.VBox()
        self.table = gtk.Table(5, 2)
        self.calendar = gtk.Calendar()
        self.hour_entry = gtk.Entry()
        self.minute_entry = gtk.Entry()
        self.msg_entry = gtk.Entry()
        self.done_msg_entry = gtk.Entry()
        self.message_label = gtk.Label()
        self.message_label.set_use_markup(True)
        self.button_box = gtk.HButtonBox()
        self.b_accept = gtk.Button(stock=gtk.STOCK_OK)
        self.b_cancel = gtk.Button(stock=gtk.STOCK_CANCEL)

        self.button_box.pack_start(self.b_accept, True, True)
        self.button_box.pack_start(self.b_cancel, True, True)
        self.button_box.set_layout(gtk.BUTTONBOX_SPREAD)
        
        self.table.attach(gtk.Label(_('Day')),0, 1, 0, 1)
        self.table.attach(self.calendar, 1, 2, 0, 1)

        self.table.attach(gtk.Label(_('Hour')), 0, 1, 1, 2)

        hbox = gtk.HBox()
        hbox.pack_start(self.hour_entry, True, True)
        hbox.pack_start(gtk.Label(':'), False)
        hbox.pack_start(self.minute_entry, True, True)

        self.table.attach(hbox, 1, 2, 1, 2 )

        self.table.attach(gtk.Label(_('Message')), 0, 1, 2, 3)
        self.table.attach(self.msg_entry, 1, 2, 2, 3)

        self.table.attach(gtk.Label(_('Done message')), 0, 1, 3, 4)
        self.table.attach(self.done_msg_entry, 1, 2, 3, 4)

        self.vbox.pack_start(self.table, True, True)
        self.vbox.pack_start(self.message_label, False)
        self.vbox.pack_start(self.button_box, False)

        self.set_values()

        self.add(self.vbox)
        self.vbox.show_all()

        self.b_accept.connect('clicked', self.on_b_accept_clicked)
        self.b_cancel.connect('clicked', self.on_b_cancel_clicked)

    def set_values(self):
        '''set the values on the widgets with the variable values'''
        self.msg_entry.set_text(self.msg)
        self.done_msg_entry.set_text(self.done_msg)
        (year, month, day, hour, minute, second, wd, jd, self.dst) = \
            time.localtime(self.stamp)

        self.hour_entry.set_text(str(hour + self.dst))
        self.minute_entry.set_text(str(minute))
        self.calendar.select_month(month - 1, year)
        self.calendar.select_day(day)

    def get_values(self):
        '''get the values from the widgets and set the variables'''
        msg = self.msg_entry.get_text()
        done_msg = self.done_msg_entry.get_text()

        try:
            hour = int(self.hour_entry.get_text())
        except ValueError:
            self.show_error(_('Invalid hour value'))
            return False
            
        try:
            minute = int(self.minute_entry.get_text())
        except ValueError:
            self.show_error(_('Invalid minute value'))
            return False

        if not (0 <= minute <= 59):
            self.show_error(_('Invalid minute value'))
            return False
        
        if not (0 <= hour <= 23):
            self.show_error(_('Invalid hour value'))
            return False

        if not msg:
            self.show_error(_('Message is empty'))
            return False
        
        if not done_msg:
            self.show_error(_('Done message is empty'))
            return False

        (year, month, day) = self.calendar.get_date()

        self.msg = msg
        self.done_msg = done_msg
        self.hour = hour
        self.minute = minute
        self.stamp = time.mktime((year, month + 1, day, hour, minute, 0,
            0, 1, self.dst))

        return True
            
    def show_error(self, message):
        '''show an error on the message label'''

        self.message_label.set_markup('<span foreground="red">%s</span>'\
            % (message,))

    def on_b_accept_clicked(self, widget):
        '''callback called on accept button clicked'''

        if self.get_values():
            self.hide()
            self.callback(self.stamp, self.msg, self.done_msg)

    def on_b_cancel_clicked(self, widget):
        '''callback called on cancel button clicked'''

        self.hide()
        
class MainClass(Plugin.Plugin):
    '''Main plugin class'''
    
    description = _('Count to a defined date')
    authors = { 'marianoguerra' : 'luismarianoguerra gmail'}
    website = 'emesene.org'
    displayName = _('Countdown')
    name = 'Countdown'
    def __init__(self, controller, msn):
        '''Contructor'''
        Plugin.Plugin.__init__(self, controller, msn)
        
        self.description = _('Count to a defined date')
        self.authors = { 'marianoguerra' : 'luismarianoguerra gmail'}
        self.website = 'emesene.org'
        self.displayName = _('Countdown')
        self.name = 'Countdown'
        self.controller = controller
        
        self.config = self.controller.config
        self.config.readPluginConfig(self.name)
        
        self.enabled = False

        self.msg = None
        self.done_msg = None
        self.target = None
        self.done = False # if we reached the date
        self.timeout = None

        self.read_config()

    def start(self):
        '''start the plugin'''
        self.enabled = True
        self.timeout = gobject.timeout_add(60000, self.refresh)
        self.read_config()
        self.refresh()

    def stop(self):    
        '''stop the plugin'''
        self.enabled = False
        gobject.source_remove(self.timeout)
        self.write_config()
        
    def check(self):
        return (True, 'Ok')

    def refresh(self):
        '''refresh the personal message with the new difference'''
        now = datetime.datetime.now()

        if now < self.target:
            delta = self.target - now
            days = delta.days
            hours = (delta.seconds / 3600)
            minutes = (delta.seconds - (hours * 3600)) / 60

            msg = self.msg.replace('%days', str(days))
            msg = msg.replace('%hours', str(hours))
            msg = msg.replace('%minutes', str(minutes))

            self.controller.contacts.set_message(msg)
        elif not self.done:
            self.controller.contacts.set_message(self.done_msg)
            self.done = True

        return True
            
    def write_config(self):
        '''save the plugin config'''
        self.config.setPluginValue(self.name, 'date', 
            str(int(time.mktime(self.target.timetuple()))))
        self.config.setPluginValue(self.name, 'msg', self.msg)
        self.config.setPluginValue(self.name, 'done_msg', self.done_msg)

    def read_config(self):
        '''read the plugin values'''
        stamp = self.config.getPluginValue(self.name, 'date', '0')
        
        self.msg = self.config.getPluginValue(self.name, 'msg',
            default_msg)
        self.done_msg = self.config.getPluginValue(self.name, 
            'done_msg', default_done_msg)

        try:
            self.target = datetime.datetime.fromtimestamp(int(stamp))
        except ValueError, value_error:
            print value_error
            self.target = datetime.datetime.fromtimestamp(0)

    def configure(self):
        '''show a config dialog to ask for the data'''

        config = ConfigWindow(self.config_callback, 
            time.mktime(self.target.timetuple()), self.msg, self.done_msg)
        config.show()

        return True

    def config_callback(self, stamp, msg, done_msg):
        '''method called from the config window when the user click accept
        and all the fields are correctly filled'''

        self.target = datetime.datetime.fromtimestamp(stamp)
        self.msg = msg
        self.done_msg = done_msg
        self.write_config()
        
        if self.enabled:
            self.refresh()
